// 实现这个项目的构建任务

/**
 * 导入需要的函数
 * src 用于源文件的地址获取
 * dest 用于文件导出使用
 * series用与同步任务
 * parallel用于异步任务
 * watch用于监听文件的变化
 */
const { src, dest, series, parallel, watch } = require("gulp");
//用于编译sass
const sass = require("gulp-sass");
//用于html的压缩
const htmlmin = require("gulp-htmlmin");
//用于js代码的转换 转换成es5等
const babel = require("gulp-babel");
//用于清空文件夹 删除上次的dist
const del = require("del");
//图片的压缩
const imageMin = require("gulp-imagemin");
//启动浏览器
const browserAync = require("browser-sync");
//资源合并
const useRef = require("gulp-useref");
//用于进行判断
const gulpIf = require("gulp-if");
//用于压缩js代码
const uglify = require("gulp-uglify");

//用于填充模板数据
const swig = require("gulp-swig");

const cleanCss = require("gulp-clean-css");

const bs = browserAync.create();

//填充模板使用的数据
const data = {
  menus: [
    {
      name: "Home",
      icon: "aperture",
      link: "index.html"
    },
    {
      name: "About",
      link: "about.html"
    },
    {
      name: "Contact",
      link: "#",
      children: [
        {
          name: "Twitter",
          link: "https://twitter.com/w_zce"
        },
        {
          name: "Baidu",
          link: "https://baidu.com"
        },
        {
          name: "divider"
        },
        {
          name: "Github",
          link: "https://github.com"
        }
      ]
    }
  ],
  pkg: require("./package.json"),
  date: new Date()
};

//构建任务

//样式文件的编译和构建
const styles = () => {
  return (
    src("src/assets/styles/*.scss", { base: "src" })
      //编译scss的文件并压缩输出
      .pipe(sass({ outputStyle: "compressed" }))
      .pipe(dest(".temp"))
  );
};

//页面 html的构建任务
const pages = () => {
  //构建html 并压缩html里面的代码
  return src("src/*.html", { base: "src" })
    .pipe(swig({ data }))
    .pipe(dest(".temp"));
};

//构建js代码
const scripts = () => {
  return src("src/assets/scripts/*.js", { base: "src" })
    .pipe(babel({ presets: ["@babel/preset-env"] }))
    .pipe(dest(".temp"));
};

//构建public下面的文件
const commons = () => {
  return src("public/**", { base: "public" }).pipe(dest("dist"));
};

//构建img的图片等资源 并压缩
const images = () => {
  return src("src/assets/images/**", { base: "src" })
    .pipe(imageMin())
    .pipe(dest("dist"));
};

//字体文件的构建 并压缩
const fonts = () => {
  return src("src/assets/fonts/**", { base: "src" })
    .pipe(imageMin())
    .pipe(dest("dist"));
};

//资源整合 同时压缩代码
const useref = () => {
  return src(".temp/*.html", { base: ".temp" })
    .pipe(useRef({ searchPath: [".temp", "."] }))
    .pipe(gulpIf(/\.*css$/, cleanCss()))
    .pipe(gulpIf(/\.js$/, uglify()))
    .pipe(
      gulpIf(
        /\.html$/,
        htmlmin({
          minifyCSS: true,
          minifyJS: true,
          removeComments: true,
          collapseWhitespace: true
        })
      )
    )
    .pipe(dest("dist"));
};

//清除文件夹
const clean = () => {
  return del(["dist", ".temp"]);
};

//开启服务
const server = () => {
  //监听文件的修改
  watch("src/assets/styles/*.scss", styles);
  watch("src/**/*.html", pages);
  watch("src/assets/scripts/*.js", scripts);
  watch("public/**", commons);

  watch(["src/assets/fonts/**", "src/assets/images/**"], bs.reload);

  bs.init({
    notify: false,
    files: ".temp/**",
    server: {
      baseDir: [".temp", "public", "src"],

      //把node_modules包含进去
      routes: {
        "/node_modules": "node_modules"
      }
    }
  });
};

const compile = parallel(styles, scripts, pages);

const build = series(
  clean,
  parallel(fonts, images, commons, series(compile, useref))
);

const serve = series(compile, server);

module.exports = {
  clean,
  build,
  serve
};
